package com.atwisdom.star.common.util;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.atwisdom.star.exception.pojo.BusinessException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.googlecode.aviator.AviatorEvaluator;
import jodd.util.StringUtil;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class JsonUtil {

    /**
     * 从一条记录中按path取出参数，存储到Map中
     * @param sourceObject
     * @param pathList
     * @param <T>
     * @return
     * @throws BusinessException
     */
    public static <T> Map<String, T> getMapOfObjectByPath(Object sourceObject, List<String> pathList) throws BusinessException {
        Map<String, T> resultMap = new HashMap<>();
        for (String path : pathList) {
            T fieldValue = get(sourceObject, String.join(".", "values", path));
            resultMap.put(path, fieldValue);
        }
        return resultMap;
    }

    public static JSONArray toJSONArray(Object sourceObject) {
        if (sourceObject instanceof String) {
            System.out.println(sourceObject);
            return JSONArray.parseArray((String) sourceObject);
        }
        return JSONArray.parseArray(JSON.toJSONString(sourceObject));
    }


    public static <T> T get(Object sourceObject, String path) throws BusinessException{
        // sourceObject = toJSONObject(sourceObject);
        if (sourceObject == null) {
            return null;
        }
        if(StringUtil.isEmpty(path)){
            return (T)sourceObject;
        }
        Object obj=sourceObject;
        if (obj instanceof List) {
            obj = JSON.parseArray(JSON.toJSONString(obj));
        } else {
            obj = toJSONObject(sourceObject);
        }
        String[] array=path.split("\\.");
        for(int i=0;i<array.length;i++){
            if (obj == null) {
                return null;
            }
            if(obj instanceof JSONObject){
                if(((JSONObject) obj).get(array[i]) instanceof JSONObject){
                    obj=((JSONObject) obj).get(array[i]);
                }else if(((JSONObject)obj).get(array[i]) instanceof JSONArray){
                    obj=((JSONObject)obj).getJSONArray(array[i]);
                }else{
                    obj=((JSONObject)obj).get(array[i]);
                }
            }else if(obj instanceof JSONArray){
                if (obj == null || ((JSONArray) obj).size() == 0) {
                    return null;
                }
                if(((JSONArray) obj).get(Integer.parseInt(array[i])) instanceof JSONObject){
                    obj=((JSONArray) obj).getJSONObject(Integer.parseInt(array[i]));
                }else if(((JSONArray) obj).get(Integer.parseInt(array[i])) instanceof JSONArray){
                    obj=((JSONArray) obj).getJSONArray(Integer.parseInt(array[i]));
                }else{
                    obj=((JSONArray)obj).get(Integer.parseInt(array[i]));
                }
            }else{
                throw new BusinessException("999999","操作异常");
            }
        }
        return (T)obj;
    }

    public static <T> List<T> getListByPath(JSONArray array, String path) throws BusinessException{
        List<T> list=new ArrayList<>();
        for(Object object:array){
            list.add(JsonUtil.get(object,path));
        }
        return list;
    }

    /**
     * 从多条记录中按path取出参数，存储到Map中
     * @param array
     * @param pathList
     * @param <T>
     * @return
     * @throws BusinessException
     */
    public static <T> Map<String, List<T>> getMapOfListByPath(JSONArray array, List<String> pathList) throws BusinessException{
        Map<String, List<T>> map = new HashMap<>(pathList.size());
        for (String path : pathList) {
            List<T> list=new ArrayList<>();
            for(Object object:array){
                list.add(JsonUtil.get(object, String.join(".", "values", path)));
            }
            map.put(path, list);
        }
        return map;
    }

    /**
     * javaBean转化为JSONObject
     * @param instance
     * @param <T>
     * @return
     */
    public static <T> JSONObject toJSONObject(T instance){
        String jsonString = JSONObject.toJSONString(instance,SerializerFeature.WriteMapNullValue);
        JSONObject jsonObject=JSONObject.parseObject(jsonString);
        return jsonObject;
    }

    public static <T> List<JSONObject> transformToJson(List<T> list) {
        return list.stream().map(d -> JsonUtil.toJSONObject(d)).collect(Collectors.toList());
    }

    public static boolean isJSONValidate(String log){
        try {
            JSON.parse(log);
            return true;
        } catch (JSONException e) {
            return false;
        }
    }

    /**
     * JSONObject转化为javaBean
     * @param jsonObject
     * @param clz
     * @param <T>
     * @return
     * 1689931152000
     */
    public static <T> T toJavaBean(JSONObject jsonObject, Class<T> clz){
        T instance = JSON.parseObject(JSON.toJSONString(jsonObject,SerializerFeature.WriteDateUseDateFormat), clz);
        return instance;
    }

    /**
     * 从JSONObject中挑选key值
     * @param jsonObject
     * @param keys
     * @return
     */
    public static JSONObject pick(JSONObject jsonObject,String [] keys){
        JSONObject res=new JSONObject();
        for(String key:keys){
            if(jsonObject.keySet().contains(key)){
                res.put(key,jsonObject.get(key));
            }
        }
        return res;
    }

    /**
     * 从javaBean中挑选key值
     * @param instance
     * @param keys
     * @param <T>
     * @return
     */
    public static <T> JSONObject pick(T instance,String [] keys){
        JSONObject jsonObject=JsonUtil.toJSONObject(instance);
        JSONObject res=new JSONObject();
        for(String key:keys){
            if(jsonObject.keySet().contains(key)){
                res.put(key,jsonObject.get(key));
            }
        }
        return res;
    }

    /**
     * 合并jsonobject
     * @param oldObject
     * @param newObject
     * @return
     */
    public static JSONObject merge(JSONObject oldObject,JSONObject newObject){
        if (oldObject ==null || newObject == null || newObject.size() < 1) {
            return oldObject;
        }

        for(String key:newObject.keySet()){
            if(oldObject.keySet().contains(key)){
                oldObject.put(key,newObject.get(key));
            }
        };
        return oldObject;
    }

    public static JSONObject buildJson(String str){
        return JSONObject.parseObject(str);
    }


    public static JSONObject buildJson(Object[] object){
        JSONObject jsonObject=new JSONObject();
        for(int i=0;i<object.length;i=i+2){
            jsonObject.put(object[i].toString(),object[i+1]);
        };
        return jsonObject;
    }

    /**
     * 处理变量，并返回变量的值
     * @param valuePointer
     * @return
     */
    public static String handleCondition(String valuePointer, JSONObject data) {
        Pattern pattern = Pattern.compile("\\$\\{(.*?)\\}");
        Matcher matcher = pattern.matcher(valuePointer);
        List<String> matches = new ArrayList<>();
        while (matcher.find()) {
            matches.add(matcher.group(1));
        }
        // 存在一个语句中有多个$的情况
        if (CollectionUtil.isNotEmpty(matches)) {
            for (String match : matches) {
                Object findResult = JsonUtil.get(data, match);
                valuePointer = valuePointer.replace("${" + match + "}", String.valueOf(findResult));
            }
        }
        return valuePointer;
    }

    /**
     * 将jsonA中的参数数据，替换到jsonB中${}包裹的内容
     * @param jsonA
     * @param jsonB
     */
    public static JSONObject replaceParam(JSONObject jsonA, JSONObject jsonB) {
        // JSONObject jsonA = JSONObject.parseObject("{\"name\":\"John\", \"age\":30, \"city\":\"New York\"}");
        // JSONObject jsonB = JSONObject.parseObject("{\"name\":\"${name}\", \"age\":\"${age}\", \"address\":{\"city\":\"${city}\"}}");

        String patternString = "\\$\\{([^}]*)\\}";
        Pattern pattern = Pattern.compile(patternString);

        String jsonString = jsonB.toString();
        Matcher matcher = pattern.matcher(jsonString);
        while (matcher.find()) {
            String match = matcher.group(1);
            Object replacement = jsonA.get(match);
            if (replacement instanceof String) {
                jsonString = jsonString.replace("${" + match + "}", (String) replacement);
            } else {
                jsonString = jsonString.replace("\"${" + match + "}\"", replacement.toString());
            }
        }

        JSONObject result = JSONObject.parseObject(jsonString);
        return result;
    }
}
